package com.boruan.shengtangfeng.api.schedule;

import java.io.File;
import java.util.*;

import javax.annotation.Resource;

import com.boruan.shengtangfeng.core.dao.*;
import com.boruan.shengtangfeng.core.entity.*;
import com.boruan.shengtangfeng.core.service.*;
import com.boruan.shengtangfeng.core.utils.UUIDUtil;
import com.tencentyun.TLSSigAPIv2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boruan.shengtangfeng.core.redis.utils.RedisAtomicClient;
import com.boruan.shengtangfeng.core.redis.utils.RedisLock;
import com.boruan.shengtangfeng.core.utils.Consts;

import cn.jpush.api.JPushClient;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
@Transactional(readOnly = false)
public class AllScheduleTask {
    @Autowired
    private RedisAtomicClient redisAtomicClient;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private IVideoDao videoDao;
    @Autowired
    private IVideoService videoService;
    @Resource(name = "jPushClient")
    private JPushClient jPushClient;

    @Autowired
    private IUserService userService;
    @Value("${tencent.secretid}")
    private Long SECRETID;
    @Value("${tencent.secretkey}")
    private String SECRETKEY;
    @Autowired
    private IApplyForDao applyForDao;
    @Value("${head.url}")
    private String headUrl;
    @Autowired
    private IOssService ossService;
    @Autowired
    private IConfigDao configDao;
    @Autowired
    private IUserCreateFansDao userCreateFansDao;
    @Autowired
    private IAttentionDao attentionDao;


    /**
     * 每隔5分钟启动
     */
    // 定时任务
    @Scheduled(cron = "0 */5 * * * ?")
    public void changeQuestionCount() {
        // 定时任务计算学生答题数
        try (RedisLock lock = redisAtomicClient.getLock(Consts.SCHEDULE_KEY_QUESTIONCOUNT, 1000 * 60 * 5)) {

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 每隔5分钟启动
     */
    // 定时任务
    @Scheduled(cron = "0 */5 * * * ?")
    public void calculateDuration() {
        // 定时任务计算视频长度
        try (RedisLock lock = redisAtomicClient.getLock(Consts.SCHEDULE_KEY_CALCULATEDURATION, 1000 * 60 * 5)) {
            List<Video> videos = videoDao.createLambdaQuery().andIsNull(Video::getDuration).andEq(Video::getIsDeleted, false).select();
            videos.forEach(video -> {
                videoService.calculateDuration(video);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 每隔1分钟启动
     */
    // 定时任务
    @Scheduled(cron = "0 * * * * ?")
    public void getUserSig() {
        List<User> userList = userDao.createLambdaQuery().andEq(User::getIsDeleted, false).select();
        for (User user : userList) {
            if (user.getUserSig() == null) {
                long expire = (long) 60 * 60 * 24 * 7;
                TLSSigAPIv2 api = new TLSSigAPIv2(SECRETID, SECRETKEY);
                String userSig = api.genSig(user.getId().toString(), expire);
                user.setUserSig(userSig);
                userDao.updateById(user);
            }
        }
    }

    /**
     * 每隔5分钟启动
     */
    // 定时获取七天前的数据，如果未操作则删除
    @Scheduled(cron = "0 */5 * * * ?")
    public void getApplyFor() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -7);
        Date date = calendar.getTime();
        List<ApplyFor> applyFors = applyForDao.createLambdaQuery().andEq(ApplyFor::getIsDeleted, false).andEq(ApplyFor::getStatus, 0).andLess(ApplyFor::getCreateTime, date).select();
        for (ApplyFor applyFor : applyFors) {
            applyFor.setIsDeleted(true);
            applyForDao.updateTemplateById(applyFor);
        }
    }

    /**
     * 每隔5分钟启动
     */
    // 定时获取七天前的数据，如果未操作则删除
    @Scheduled(cron = "0 */5 * * * ?")
    public void getC() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -7);
        Date date = calendar.getTime();
        List<ApplyFor> applyFors = applyForDao.createLambdaQuery().andEq(ApplyFor::getIsDeleted, false).andEq(ApplyFor::getStatus, 0).andLess(ApplyFor::getCreateTime, date).select();
        for (ApplyFor applyFor : applyFors) {
            applyFor.setIsDeleted(true);
            applyForDao.updateTemplateById(applyFor);
        }
    }

    /**
     * 两分钟执行一次，为用户生成账号
     */
    @Scheduled(cron = "0 */2 * * * ?")
    public void createUserAccount() {
        RedisLock redisLock = redisAtomicClient.getLock("create_user_account", 60 * 1000 * 2);
        if (redisLock != null) {
            List<User> userList = userDao.createLambdaQuery().andIsNull(User::getAccount).andEq(User::getIsDeleted, false).select();
            try {
                for (User user : userList) {
                    Integer len = Math.toIntExact(8 - (user.getId() + "").length());
                    user.setAccount(user.getId() + UUIDUtil.differentDigitsRandom(len));
                    userDao.updateTemplateById(user);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                redisLock.unlock();
            }
        }
    }

    /**
     * 两分钟执行一次，为机器人用户添加头像
     */
    @Scheduled(cron = "0 */2 * * * ?")
    public void robotUserImage() {
        RedisLock redisLock = redisAtomicClient.getLock("robot_user_image", 60 * 1000 * 2);
        if (redisLock != null) {
            List<User> userList = userDao.createLambdaQuery().andEq(User::getType, 1).andIsNull(User::getHeadImage).andEq(User::getIsDeleted, false).select();
            try {
                File file = new File(headUrl);
                if(file != null){
                    List<File> files = Arrays.asList(file.listFiles());
                    int index = new Random().nextInt(files.size() - 1);
                    for (User user : userList) {
                        String url = ossService.uploadObject2OSS(new File(files.get(index).toString()));
                        if (url != null && !url.equals("")) {
                            user.setHeadImage(url);
                            user.setUpdateTime(new Date());
                            userDao.updateTemplateById(user);

                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                redisLock.unlock();
            }
        }
    }

    /**
     * 每晚零点点启动一次，给新注册用户增加粉丝
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void giveNewUserFans() {
        RedisLock redisLock = redisAtomicClient.getLock("give_new user_fans", 60 * 1000);
        if (redisLock != null) {
            Config fansday = configDao.getKey(Consts.CONFIG_FANS_DAY);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, -Integer.valueOf(fansday.getValue()));
            Date date = calendar.getTime();
            List<User> userList = userDao.createLambdaQuery().andEq(User::getIsDeleted, false).andEq(User::getType, 0).andGreatEq(User::getCreateTime, date).select();
            for (User user : userList) {
                List<UserCreateFans> fansList = userCreateFansDao.createLambdaQuery().andEq(UserCreateFans::getUserId, user.getId()).andEq(UserCreateFans::getIsDeleted, false).andEq(UserCreateFans::getIsExecute, 0).select();
                UserCreateFans userCreateFans = fansList.get(0);
                List<User> robotlist = userDao.getNotAttentionRobot(user.getId(),userCreateFans.getFansNum());
                ArrayList<Attention> attentions = new ArrayList<>();
                for (User robot : robotlist) {
                    Attention attention = new Attention();
                    attention.setUserId(robot.getId());
                    attention.setFocusUserId(user.getId());
                    attention.setCreateTime(new Date());
                    attention.setIsDeleted(false);
                    attentions.add(attention);
                }
                if (robotlist.size()<userCreateFans.getFansNum()){
                    for (int i = 0; i < userCreateFans.getFansNum() - robotlist.size(); i++) {
                        User robotUser = userService.createRobotUser();
                        Attention attention = new Attention();
                        attention.setUserId(robotUser.getId());
                        attention.setFocusUserId(user.getId());
                        attention.setCreateTime(new Date());
                        attention.setIsDeleted(false);
                        attentions.add(attention);
                    }
                }
                attentionDao.insertBatch(attentions);
                userCreateFans.setIsExecute(1);
                userCreateFans.setUpdateTime(new Date());
                userCreateFansDao.updateTemplateById(userCreateFans);
            }
        }
    }

    /**
     * 两分钟执行一次，为机器人用户添加头像
     */
    @Scheduled(cron = "*/30 * * * * ?")
    public void updateOSSDNS() {
        RedisLock redisLock = redisAtomicClient.getLock("update_OSS_DNS", 60 * 1000);
        if (redisLock != null) {
            try {
                videoDao.updateOSSDNS();
                videoDao.updateOSSDNS1();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                redisLock.unlock();
            }
        }
    }
}
